Subscript ranges are used to select a subarray from an array by giving the starting and ending subscripts of the subarray in each dimension. Subscript ranges can be combined with scalar and array subscripts and with other subscript ranges. Any rectangular portion of an array can be selected with subscript ranges.
There are six types of subscript ranges:
Multidimensional subarrays can be specified using any combination of the above forms. For example, if arr is a 10x10 array, arr[*,0:4] returns a 10 x 5 array that is made from all columns of rows 0 to 4 of arr.
The dimensions of an extracted subarray are determined by the size in each dimension of the subscript range expression. In general, the number of dimensions is equal to the number of subscripts and subscript ranges. The size of the n-th dimension is equal to one if a simple subscript was used to specify that dimension in the subscript; otherwise, it is equal to the number of elements selected by the corresponding range expression.
Degenerate dimensions (trailing dimensions with a size of one) are removed. If arr is a 10-column by 12-row array, the expression arr[*,11] results in a row vector with a single dimension. (The result of the expression is a 10-column by 1-row array; the last dimension is degenerate and is removed.) On the other hand, the expression arr[0, *] became a column vector with dimensions of [1, 12], showing that the structure of columns is preserved because the dimension with a size of one does not appear at the end.
To see this, enter the following statements in IDL:
arr = INDGEN(10,12)
HELP, arr
HELP, arr[*,11]
HELP, arr[0,*]
In the following examples, vec is a 50-element floating-point vector, and arr is a 10-column by 12-row integer array. Some typical subscript range expressions are as follows:
vec = BINDGEN(50)
arr = BINDGEN(10,12)
; Elements 5 through 10 of vec, a six-element vector.
print, vec[5:10]
; A three-element vector.
I = 25
print, vec[I - 1:I + 1]
; The same vector.
print, [vec[I - 1], vec[I], vec[I + 1]]
; Elements from vec[4] to the end, a 46-element (50-4) vector.
print, vec[4:*]
; Values of the elements with even subscripts in vec.
print, vec[0:*:2]
; The same as above, but in reverse order.
print, vec[-2:0:-2]
; Values of the elements with odd subscripts in vec:
print, vec[1:*:2]
; The same as above, but in reverse order.
print, vec[-1:0:-2]
; The fourth column of arr, a 1 column by 12 row vector.
print, arr[3, *]
; The first row of arr, a 10-element row vector. Note, the last
; dimension was removed because it was degenerate.
print, arr[*, 0]
; The nine-point neighborhood surrounding arr[X,Y], a 3 by 3 array.
X = 3
Y = 4
print, arr[X - 1:X + 1, Y - 1:Y + 1]
; Three columns of arr, a 3 by 12 subarray:
print, arr[3:5,*]
; The same three columns of arr, with the columns reversed:
print, arr[5:3:-1,*]
To insert the contents of an array called A into array B, starting at point B[13, 24], use the following statement:
B[13, 24] = A
If A is a 5-column by 6-row array, elements B[13:17, 24:29] are replaced by the contents of array A.
In the next example, a subarray is moved from one position to another:
B[100, 200] = B[200:300, 300:400]
A subarray of B, specifically the columns 200 to 300 and rows 300 to 400, is moved to columns 100 to 200 and rows 200 to 300, respectively.
Assuming the variable B is a 512 x 512-byte array, some examples are as follows:
; Store 1 in every element of the i-th row.
array[*, I] = 1
; Store 1 in every element of the j-th column.
array[J, *] = 1
; Zero all the rows of columns 200 through 220 of array.
array[200:220, *] = 0
; Zero the last 5 rows of columns 200 through 220 of array.
array[200:220, -5:-1] = 0
; Store the value 100 in all the elements of array.
array[*] = 100
It is possible to use range subscripts in an assignment statement, however, when possible, you should avoid using range subscripts in favor of using scalar or array subscripts. This type of assignment statement takes the following form:
Variable[Subscript_Range] = Expression
A subscript range specifies a beginning and ending subscripts, which are separated by the colon character. An ending subscript equal to the size of the dimension minus one can be written as *. For example, arr[I:J] denotes those points in the vector arr with subscripts between I and J inclusive. I must be less than or equal to J and greater than or equal to zero. See above for more details on subscript ranges.
When possible, you should avoid using range subscripts in favor of using scalar or array subscripts. In the following example, the array elements of X are inserted into array A. The slow way uses subscript ranges, specifying the insertion of X array elements into the 5th through 7th elements of A. The fast way uses a scalar subscript specifying the first element (the 5th) to be replaced with the elements of A.
A = INTARR(10)
X = [1,1,1]
PRINT, 'A = ', A
; Slow way:
t = SYSTIME(1) & FOR i=0L,100000 DO A[4:6] = X &
PRINT,'Slow way: ', SYSTIME(1)-t
PRINT, 'A = ', A
; Correct way is 4 times faster:
t = SYSTIME(1) & FOR i=0L,100000 DO A[4] = X &
PRINT, 'Fast way: ', SYSTIME(1)-t
PRINT, 'A = ', A
IDL prints:
A = 0 0 0 0 0 0 0 0 0 0
Slow way: 0.47000003
A = 0 0 0 0 1 1 1 0 0 0
Fast way: 0.12100005
A = 0 0 0 0 1 1 1 0 0 0
The statement A[4] = X, where X is a three-element array, causes IDL to start at index 4 of array A, and replace the next three elements in A with the elements in X. Because of the way it is implemented in IDL, A[4] = X is much more efficient than A[4:6] = X.